package mi.payment.transaction;

import android.text.TextUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import lainey.ui.utils.LogUtil;
import mi.payment.CardType;
import mi.payment.Constant;
import mi.payment.bean.db.CardInfo;
import mi.payment.bean.db.ICCardInfo;
import mi.payment.bean.db.MAGCardInfo;
import mi.payment.bean.db.TradeData;
import mi.payment.db.dao.PayDetail;
import mi.payment.settings.SystemParamsOperation;
import mi.payment.utils.Track2Util;
import mi.payment.utils.UnionPayUtil;
import mi.payment.utils.iso8583.TLV;
import mi.payment.utils.iso8583.TLVUtils;
import mi.payment.utils.iso8583.Utils;
import mi.payment.utils.secure.TrackEncrypt;

public class KernelDataProcessUtil {

    public static com.sunmi.pay.hardware.aidl.bean.CardInfo getCardInfo(int cardType, byte[] data) {
        Map<String, TLV> tlvMap = TLVUtils.builderTLVMap(data);
        com.sunmi.pay.hardware.aidl.bean.CardInfo cardInfo = new com.sunmi.pay.hardware.aidl.bean.CardInfo();

        // 二磁
        TLV tlv = tlvMap.get("57");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue().toUpperCase();
            cardInfo = Track2Util.parseTrack2(value);
            cardInfo.track2 = value.replaceAll("F", ""); // 去掉二磁后面的F
        }

        // IC卡通过5A和5F24获取卡号和有效期
        if (CardType.IC.getValue() == cardType) {

            // 卡号
            tlv = tlvMap.get("5A");
            if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
                String value = tlv.getValue().toUpperCase().replaceAll("F", ""); // 去掉卡号的F
                cardInfo.cardNo = value;
                LogUtil.e(Constant.TAG, "卡号为：" + value);
            }

            // 卡有效期
            tlv = tlvMap.get("5F24");
            if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
                String value = tlv.getValue().toUpperCase();
                if (value.length() > 4) {
                    cardInfo.expireDate = value.substring(0, 4); // 取有效期的年月
                } else {
                    cardInfo.expireDate = value;
                }
                LogUtil.e(Constant.TAG, "卡有效期为：" + value);
            }

        }

        // 卡片序列号
        tlv = tlvMap.get("5F34");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue().toUpperCase();
            if (value.trim().length() == 0) {
                cardInfo.isCardSerialNo = false;
            } else {
                cardInfo.isCardSerialNo = true;
                cardInfo.cardSerialNo = value;
                LogUtil.e(Constant.TAG, "卡片序列号为：" + value);
            }
        } else {
            cardInfo.isCardSerialNo = false;
        }

        // 等效二磁 IC卡磁条模式
        tlv = tlvMap.get("9F6B");
        boolean judge = (cardInfo.cardNo == null || cardInfo.cardNo.length() == 0) &&
                (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0);
        if (judge) {
            String value = tlv.getValue().toUpperCase();
            cardInfo = Track2Util.parseTrack2(value);
            cardInfo.track2 = value.replaceAll("F", "");
        }

        cardInfo.cardType = cardType;
        return cardInfo;
    }

    public static TradeData fillTradeDataInfo(com.sunmi.pay.hardware.aidl.bean.CardInfo cardInfo, TradeData tradeData) {
        PayDetail payDetail = tradeData.getPayDetail();
        if (cardInfo.expireDate != null && cardInfo.expireDate.length() > 4) {
            cardInfo.expireDate = cardInfo.expireDate.substring(0, 4);
        }
        payDetail.setCardNo(cardInfo.cardNo);
        payDetail.setCardType(cardInfo.cardType);
        payDetail.setEXPDate(cardInfo.expireDate);
        if (cardInfo.cardSerialNo != null) {
            try {
                int parseInt = Integer.parseInt(cardInfo.cardSerialNo);
                String cardSerialNo = String.format("%03d", parseInt);
                payDetail.setCardSerialNo(cardSerialNo);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        MAGCardInfo magCardInfo = tradeData.getCardInfo().getMAGCardInfo();
        magCardInfo.setTrack1(cardInfo.track1);
        String track2 = cardInfo.track2;
        if (track2 != null && track2.length() > 0) {
            magCardInfo.setTrack2(track2);
            String track2Encrypt = TrackEncrypt.trackEncrypt(track2);
            magCardInfo.setTrack2Cipher(track2Encrypt);
        }
        String track3 = cardInfo.track3;
        if (track3 != null && track3.length() > 0) {
            magCardInfo.setTrack3(track3);
            String track3Encrypt = TrackEncrypt.trackEncrypt(track3);
            magCardInfo.setTrack3Cipher(track3Encrypt);
        }
        if (CardType.IC.getValue() == cardInfo.cardType) {
            magCardInfo.setIccCard(true);
        }
        magCardInfo.setExpireDate(cardInfo.expireDate);
        magCardInfo.setCountryCode(cardInfo.countryCode);
        return tradeData;
    }

    public static TradeData readNonContactFreeData(byte[] bytes, TradeData tradeData) {
        String icData = Utils.Bcd2String(bytes).toUpperCase();
        Map<String, TLV> tags = TLVUtils.builderTLVMap(icData);
        // 非接卡AID
        TLV tlv = tags.get("4F");
        if (tlv != null) {
            String value = tlv.getValue();
            tradeData.setDataTag4F(value);
        }
        // 非接卡获取到的 9F6C卡片终端协商结果要求Pin
        tlv = tags.get("9F6C");
        if (tlv != null) {
            String value = tlv.getValue();
            tradeData.setDataTag9F6C(value);
        }
        return tradeData;
    }

    public static TradeData readKernelData(byte[] bytes, TradeData tradeData) {
        PayDetail payDetail = tradeData.getPayDetail();
        payDetail.setEmvData(bytes);
        int cardType = payDetail.getCardType();
        CardInfo cardInfo = tradeData.getCardInfo();
        ICCardInfo icCardInfo = cardInfo.getICCardInfo();
        MAGCardInfo magCardInfo = cardInfo.getMAGCardInfo();
        String icData = Utils.Bcd2String(bytes).toUpperCase();
        Map<String, TLV> tlvMap = TLVUtils.builderTLVMap(icData);

        LogUtil.e(Constant.TAG, "icData:" + icData);

        // 密码密文
        TLV tlv = tlvMap.get("DF02");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue();
            payDetail.setPINCipher(value);
        }

        // 主账号序号（针对IC卡）
        String panSubNo = "000";
        tlv = tlvMap.get("5F34");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            try {
                String value = tlv.getValue();
                int parseInt = Integer.parseInt(value);
                panSubNo = String.format("%03d", parseInt);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        payDetail.setCardSerialNo(panSubNo);

        // AID
        tlv = tlvMap.get("9F06");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue();
            icCardInfo.setAID(value);
            payDetail.setAID(value);
            String accountType = UnionPayUtil.getAccountType(value);
            payDetail.setAccountType(accountType);
        }

        // 应用标签
        tlv = tlvMap.get("FF30");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue();
            icCardInfo.setAppLabel(value);
            payDetail.setAppLabel(value);
        }

        // 应用首选名称
        tlv = tlvMap.get("FF31");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue();
            icCardInfo.setAppName(value);
            payDetail.setAppName(value);
        }

        // TVR 终端验证结果
        tlv = tlvMap.get("95");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            if (CardType.NFC.getValue() == cardType) {
                icCardInfo.setTVR("0000000000");
                payDetail.setTVR("0000000000");
            } else {
                String value = tlv.getValue();
                icCardInfo.setTVR(value);
                payDetail.setTVR(value);
            }
        }

        // TSI 交易状态信息
        tlv = tlvMap.get("9B");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue();
            icCardInfo.setTSI(value);
            payDetail.setTSI(value);
        }

        // ATC 应用交易计数器
        tlv = tlvMap.get("9F36");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue();
            icCardInfo.setATC(value);
            payDetail.setATC(value);
        }

        // ARQc 应用密文数据 AC
        tlv = tlvMap.get("9F26");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue();
            icCardInfo.setARqC(value);
            payDetail.setArqC(value);
        }

        // 脚本处理结果
        tlv = tlvMap.get("DF31");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue();
            icCardInfo.setScriptResult(value);
            payDetail.setScriptResult(value);
        }

        // 密文信息数据
        tlv = tlvMap.get("9F27");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue();
            icCardInfo.setCID(value);
            payDetail.setCID(value);
        }

        // 二磁
        boolean isEqualTrack2 = true;
        tlv = tlvMap.get("57");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            isEqualTrack2 = false;
            String value = tlv.getValue();
            int indexOf = value.indexOf("F");
            if (indexOf > 0) {
                String str = value.substring(0, indexOf);
                magCardInfo.setTrack2(str);
            } else {
                magCardInfo.setTrack2(value);
            }
            // 加密二磁道
            String track2 = magCardInfo.getTrack2();
            String track2Encrypt = TrackEncrypt.trackEncrypt(track2);
            magCardInfo.setTrack2Cipher(track2Encrypt);
        }

        // 等效二磁 IC卡磁条模式
        tlv = tlvMap.get("9F6B");
        if (isEqualTrack2 && tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue();
            int indexOf = value.indexOf("F");
            if (indexOf > 0) {
                String str = value.substring(0, indexOf);
                magCardInfo.setTrack2(str);
            } else {
                magCardInfo.setTrack2(value);
            }
            // 加密二磁道
            String track2 = magCardInfo.getTrack2();
            String track2Encrypt = TrackEncrypt.trackEncrypt(track2);
            magCardInfo.setTrack2Cipher(track2Encrypt);
        }

        // PAN
        tlv = tlvMap.get("5A");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue();
            // 去掉卡号中的F
            String cardNo = value.toUpperCase().replaceAll("F", "");
            payDetail.setCardNo(cardNo);
        } else if (magCardInfo.getTrack2() != null) { // 从二磁中取卡号
            int indexOf = magCardInfo.getTrack2().indexOf("D");
            if (indexOf != -1) {
                String cardNo = magCardInfo.getTrack2().substring(0, indexOf);
                payDetail.setCardNo(cardNo);
            }
        }

        // 卡有效期
        String expireDate = "";
        tlv = tlvMap.get("5F24");
        if (tlv != null && tlv.getValue() != null && tlv.getValue().length() > 0) {
            String value = tlv.getValue();
            if (value.length() > 4) { // 取有效期的年月
                expireDate = value.substring(0, 4);
            } else {
                expireDate = value;
            }
        } else if (magCardInfo.getTrack2() != null) { // 从二磁中取卡有效期
            int indexOf = magCardInfo.getTrack2().indexOf("D");
            if (indexOf != -1) {
                expireDate = magCardInfo.getTrack2().substring(indexOf + 1, indexOf + 5);
            }
        }
        if (expireDate.length() >= 4) {
            payDetail.EXPDate = expireDate.substring(0, 4);
        }

        // 55 域
        String f55DataStr = "";

        // 应用密文（AC）
        if (tlvMap.get("9F26") != null) {
            f55DataStr += "9F2608" + tlvMap.get("9F26").getValue();
        }

        // 密文信息数据（CID）
        if (tlvMap.get("9F27") != null) {
            f55DataStr += "9F2701" + tlvMap.get("9F27").getValue();
        }

        // 发卡行应用数据
        if (tlvMap.get("9F10") != null) {
            int length = tlvMap.get("9F10").getLength();
            f55DataStr += "9F10" + String.format("%02X", length) + tlvMap.get("9F10").getValue();
        }

        // 不可预知数
        if (tlvMap.get("9F37") != null) {
            f55DataStr += "9F3704" + tlvMap.get("9F37").getValue();
        }

        // 应用交易计数器（ATC）
        if (tlvMap.get("9F36") != null) {
            f55DataStr += "9F3602" + tlvMap.get("9F36").getValue();
        }

        // 终端验证结果（TVR）
        if (tlvMap.get("95") != null) {
            f55DataStr += "9505" + tlvMap.get("95").getValue();
        }

        if (tlvMap.get("9A") != null) {
            f55DataStr += "9A03" + tlvMap.get("9A").getValue();
        } else {
            SimpleDateFormat df = new SimpleDateFormat("yyMMdd");
            Date date = new Date();
            String format = df.format(date);
            f55DataStr += "9A03" + format;
        }

        if (tlvMap.get("9C") != null) {
            f55DataStr += "9C01" + tlvMap.get("9C").getValue();
        } else {
            f55DataStr += "9C0100";
        }

        // 授权金额
        if (tlvMap.get("9F02") != null) {
            f55DataStr += "9F0206" + tlvMap.get("9F02").getValue();
        }

        // 交易货币代码
        if (tlvMap.get("5F2A") != null) {
            f55DataStr += "5F2A02" + tlvMap.get("5F2A").getValue();
        } else {
            f55DataStr += "5F2A020156";
        }

        // 应用交互特征
        if (tlvMap.get("82") != null) {
            f55DataStr += "8202" + tlvMap.get("82").getValue();
        }

        // 终端国家代码
        if (tlvMap.get("9F1A") != null) {
            String value = tlvMap.get("9F1A").getValue();
            value = TextUtils.equals("0000", value) ? "0156" : value;
            f55DataStr += "9F1A02" + value;
        } else {
            f55DataStr += "9F1A020156";
        }

        // 其他金额
        if (tlvMap.get("9F03") != null) {
            f55DataStr += "9F0306" + tlvMap.get("9F03").getValue();
        } else {
            f55DataStr += "9F0306000000000000";
        }

        // 终端性能
        if (tlvMap.get("9F33") != null) {
            f55DataStr += "9F3303" + tlvMap.get("9F33").getValue();
        } else {
            f55DataStr += "9F330360F800";
        }

        // 持卡人验证方法结果CVM
        if (tlvMap.get("9F34") != null) {
            f55DataStr += "9F3403" + tlvMap.get("9F34").getValue();
        } else {
            f55DataStr += "9F34031F0302";
        }

        // 终端类型
        if (tlvMap.get("9F35") != null) {
            f55DataStr += "9F3501" + tlvMap.get("9F35").getValue();
        } else {
            f55DataStr += "9F350121";
        }

        if (tlvMap.get("9F1E") != null) {
            f55DataStr += "9F1E08" + tlvMap.get("9F1E").getValue();
        } else {
            f55DataStr += "9F1E083730303030303034";
        }

        // 专用DF文件名称
        if (tlvMap.get("84") != null) {
            String value = tlvMap.get("84").getValue();
            String length = TLVUtils.TLVValueLengthToHexString(value.length() / 2);
            f55DataStr += "84" + length + value;
        } else {
            if (tlvMap.get("9F06") != null) {
                String value = tlvMap.get("9F06").getValue();
                String length = TLVUtils.TLVValueLengthToHexString(value.length() / 2);
                f55DataStr += "84" + length + value;
            } else {
                if (tlvMap.get("4F") != null) {
                    String value = tlvMap.get("4F").getValue();
                    String length = TLVUtils.TLVValueLengthToHexString(value.length() / 2);
                    f55DataStr += "84" + length + value;
                } else {
                    f55DataStr += "8408A000000333010102";
                }
            }
        }

        // 应用版本号
        if (tlvMap.get("9F09") != null) {
            tlv = tlvMap.get("9F09");
            String value = tlv.getValue();
            int length = tlv.getLength();
            String len = getHexLen(length);
            f55DataStr += "9F09" + len + "008D";
        }

        // 交易序列计数器
        if (tlvMap.get("9F41") != null) {
            int length = tlvMap.get("9F41").getLength();
            f55DataStr += "9F41" + String.format("%02d", length) + tlvMap.get("9F41").getValue();
        } else {
            String batchNumStart = SystemParamsOperation.getInstance().getSystemParamsSettings().getBatchNumStart();
            try {
                int parseInt = Integer.parseInt(batchNumStart);
                String value = String.format("%06d", parseInt);
                f55DataStr += "9F4103" + value;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        if (tlvMap.get("50") != null) {
            tlv = tlvMap.get("50");
            String value = tlv.getValue();
            int length = tlv.getLength();
            String len = getHexLen(length);
            f55DataStr += "50" + len + value;
        }

        if (tlvMap.get("5F34") != null) {
            tlv = tlvMap.get("5F34");
            String value = tlv.getValue();
            int length = tlv.getLength();
            String len = getHexLen(length);
            f55DataStr += "5F34" + len + value;
        }

        if (tlvMap.get("4F") != null) {
            tlv = tlvMap.get("4F");
            String value = tlv.getValue();
            int length = tlv.getLength();
            String len = getHexLen(length);
            f55DataStr += "4F" + len + value;
        }

        if (tlvMap.get("9F0E") != null) {
            tlv = tlvMap.get("9F0E");
            String value = tlv.getValue();
            int length = tlv.getLength();
            String len = getHexLen(length);
            f55DataStr += "9F0E" + len + value;
        }

        if (tlvMap.get("9F0F") != null) {
            tlv = tlvMap.get("9F0F");
            String value = tlv.getValue();
            int length = tlv.getLength();
            String len = getHexLen(length);
            f55DataStr += "9F0F" + len + value;
        }

        if (tlvMap.get("9F0D") != null) {
            tlv = tlvMap.get("9F0D");
            String value = tlv.getValue();
            int length = tlv.getLength();
            String len = getHexLen(length);
            f55DataStr += "9F0D" + len + value;
        }

        if (tlvMap.get("9F08") != null) {
            tlv = tlvMap.get("9F08");
            String value = tlv.getValue();
            int length = tlv.getLength();
            String len = getHexLen(length);
            f55DataStr += "9F08" + len + value;
        }
        icCardInfo.setICC55(f55DataStr);
        payDetail.setICC55(f55DataStr);
        tradeData.setPayDetail(payDetail);
        return tradeData;
    }

    private static String getHexLen(int len) {
        String str = Integer.toHexString(len);
        if (str.length() == 1) {
            str = "0" + str;
        }
        return str;
    }

}
